﻿# 智能客服系统自动启动脚本

# 设置控制台编码
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8

Write-Host ""
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "    智能客服系统自动启动器" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""

# 检查并停止现有进程
Write-Host "[1/5] 检查并停止现有进程..." -ForegroundColor Yellow
 = Get-Process | Where-Object {.ProcessName -like "*SmartCustomerService*"}
if () {
    Write-Host "发现现有进程，正在停止..." -ForegroundColor Yellow
     | Stop-Process -Force
    Start-Sleep -Seconds 2
}
Write-Host " 清理完成" -ForegroundColor Green

# 检查端口占用
Write-Host ""
Write-Host "[2/5] 检查端口占用..." -ForegroundColor Yellow
try {
     = Get-NetTCPConnection -LocalPort 5001 -ErrorAction SilentlyContinue
     = Get-NetTCPConnection -LocalPort 5000 -ErrorAction SilentlyContinue

    if ( -or ) {
        Write-Host "端口被占用，正在清理..." -ForegroundColor Yellow
        if () {  | ForEach-Object { Stop-Process -Id .OwningProcess -Force -ErrorAction SilentlyContinue } }
        if () {  | ForEach-Object { Stop-Process -Id .OwningProcess -Force -ErrorAction SilentlyContinue } }
        Start-Sleep -Seconds 2
    }
} catch {
    Write-Host "端口检查跳过（权限不足）" -ForegroundColor Yellow
}
Write-Host " 端口清理完成" -ForegroundColor Green

# 启动应用
Write-Host ""
Write-Host "[3/5] 启动应用..." -ForegroundColor Yellow
Set-Location "SmartCustomerService.Web"

# 使用 Start-Process 启动应用
 = Start-Process -FilePath "dotnet" -ArgumentList "run" -PassThru -WindowStyle Hidden
Write-Host " 应用启动中 (PID: )" -ForegroundColor Green

# 等待应用启动
Write-Host ""
Write-Host "[4/5] 等待应用完全启动..." -ForegroundColor Yellow
 = 30
 = 0
 = False

while ( -lt  -and -not ) {
    Start-Sleep -Seconds 1
    ++
    
     = netstat -an | findstr :5001
    if () {
         = True
        Write-Host " 应用启动成功！" -ForegroundColor Green
    } else {
        Write-Host "." -NoNewline -ForegroundColor Gray
    }
}

if (-not ) {
    Write-Host ""
    Write-Host " 应用启动超时" -ForegroundColor Red
    exit 1
}

# 测试 Swagger 端点
Write-Host ""
Write-Host "[5/5] 测试 Swagger 端点..." -ForegroundColor Yellow
 = False
 = 10
 = 0

while ( -lt  -and -not ) {
    try {
        <!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>?????????????????? API ??????</title>
    <link rel="stylesheet" type="text/css" href="./swagger-ui.css">
    <link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
    <link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
    <style>

        html {
            box-sizing: border-box;
            overflow: -moz-scrollbars-vertical;
            overflow-y: scroll;
        }

        *,
        *:before,
        *:after {
            box-sizing: inherit;
        }

        body {
            margin: 0;
            background: #fafafa;
        }
    </style>
    
</head>

<body>
    <div id="swagger-ui"></div>

    <!-- Workaround for https://github.com/swagger-api/swagger-editor/issues/1371 -->
    <script>
        if (window.navigator.userAgent.indexOf("Edge") > -1) {
            console.log("Removing native Edge fetch in favor of swagger-ui's polyfill")
            window.fetch = undefined;
        }
    </script>

    <script src="./swagger-ui-bundle.js"></script>
    <script src="./swagger-ui-standalone-preset.js"></script>
    <script>
        /* Source: https://gist.github.com/lamberta/3768814
         * Parse a string function definition and return a function object. Does not use eval.
         * @param {string} str
         * @return {function}
         *
         * Example:
         *  var f = function (x, y) { return x * y; };
         *  var g = parseFunction(f.toString());
         *  g(33, 3); //=> 99
         */
        function parseFunction(str) {
            if (!str) return void (0);

            var fn_body_idx = str.indexOf('{'),
                fn_body = str.substring(fn_body_idx + 1, str.lastIndexOf('}')),
                fn_declare = str.substring(0, fn_body_idx),
                fn_params = fn_declare.substring(fn_declare.indexOf('(') + 1, fn_declare.lastIndexOf(')')),
                args = fn_params.split(',');

            args.push(fn_body);

            function Fn() {
                return Function.apply(this, args);
            }
            Fn.prototype = Function.prototype;

            return new Fn();
        }

        window.onload = function () {
            var configObject = JSON.parse('{"urls":[{"url":"/swagger/v1/swagger.json","name":"\u667A\u80FD\u5BA2\u670D\u7CFB\u7EDF API v1"}],"deepLinking":false,"persistAuthorization":false,"displayOperationId":false,"defaultModelsExpandDepth":-1,"defaultModelExpandDepth":1,"defaultModelRendering":"example","displayRequestDuration":true,"docExpansion":"list","showExtensions":false,"showCommonExtensions":false,"supportedSubmitMethods":["get","put","post","delete","options","head","patch","trace"],"tryItOutEnabled":false}');
            var oauthConfigObject = JSON.parse('{"scopeSeparator":" ","scopes":[],"useBasicAuthenticationWithAccessCodeGrant":false,"usePkceWithAuthorizationCodeGrant":false}');

            // Workaround for https://github.com/swagger-api/swagger-ui/issues/5945
            configObject.urls.forEach(function (item) {
                if (item.url.startsWith("http") || item.url.startsWith("/")) return;
                item.url = window.location.href.replace("index.html", item.url).split('#')[0];
            });

            // If validatorUrl is not explicitly provided, disable the feature by setting to null
            if (!configObject.hasOwnProperty("validatorUrl"))
                configObject.validatorUrl = null

            // If oauth2RedirectUrl isn't specified, use the built-in default
            if (!configObject.hasOwnProperty("oauth2RedirectUrl"))
                configObject.oauth2RedirectUrl = (new URL("oauth2-redirect.html", window.location.href)).href;

            // Apply mandatory parameters
            configObject.dom_id = "#swagger-ui";
            configObject.presets = [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset];
            configObject.layout = "StandaloneLayout";

            // Parse and add interceptor functions
            var interceptors = JSON.parse('{"RequestInterceptorFunction":null,"ResponseInterceptorFunction":null}');
            if (interceptors.RequestInterceptorFunction)
                configObject.requestInterceptor = parseFunction(interceptors.RequestInterceptorFunction);
            if (interceptors.ResponseInterceptorFunction)
                configObject.responseInterceptor = parseFunction(interceptors.ResponseInterceptorFunction);

            // Begin Swagger UI call region

            const ui = SwaggerUIBundle(configObject);

            ui.initOAuth(oauthConfigObject);

            // End Swagger UI call region

            window.ui = ui
        }
    </script>
</body>
</html>
 = Invoke-WebRequest -Uri "http://localhost:5000/swagger" -UseBasicParsing -TimeoutSec 5
        if (<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>?????????????????? API ??????</title>
    <link rel="stylesheet" type="text/css" href="./swagger-ui.css">
    <link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
    <link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
    <style>

        html {
            box-sizing: border-box;
            overflow: -moz-scrollbars-vertical;
            overflow-y: scroll;
        }

        *,
        *:before,
        *:after {
            box-sizing: inherit;
        }

        body {
            margin: 0;
            background: #fafafa;
        }
    </style>
    
</head>

<body>
    <div id="swagger-ui"></div>

    <!-- Workaround for https://github.com/swagger-api/swagger-editor/issues/1371 -->
    <script>
        if (window.navigator.userAgent.indexOf("Edge") > -1) {
            console.log("Removing native Edge fetch in favor of swagger-ui's polyfill")
            window.fetch = undefined;
        }
    </script>

    <script src="./swagger-ui-bundle.js"></script>
    <script src="./swagger-ui-standalone-preset.js"></script>
    <script>
        /* Source: https://gist.github.com/lamberta/3768814
         * Parse a string function definition and return a function object. Does not use eval.
         * @param {string} str
         * @return {function}
         *
         * Example:
         *  var f = function (x, y) { return x * y; };
         *  var g = parseFunction(f.toString());
         *  g(33, 3); //=> 99
         */
        function parseFunction(str) {
            if (!str) return void (0);

            var fn_body_idx = str.indexOf('{'),
                fn_body = str.substring(fn_body_idx + 1, str.lastIndexOf('}')),
                fn_declare = str.substring(0, fn_body_idx),
                fn_params = fn_declare.substring(fn_declare.indexOf('(') + 1, fn_declare.lastIndexOf(')')),
                args = fn_params.split(',');

            args.push(fn_body);

            function Fn() {
                return Function.apply(this, args);
            }
            Fn.prototype = Function.prototype;

            return new Fn();
        }

        window.onload = function () {
            var configObject = JSON.parse('{"urls":[{"url":"/swagger/v1/swagger.json","name":"\u667A\u80FD\u5BA2\u670D\u7CFB\u7EDF API v1"}],"deepLinking":false,"persistAuthorization":false,"displayOperationId":false,"defaultModelsExpandDepth":-1,"defaultModelExpandDepth":1,"defaultModelRendering":"example","displayRequestDuration":true,"docExpansion":"list","showExtensions":false,"showCommonExtensions":false,"supportedSubmitMethods":["get","put","post","delete","options","head","patch","trace"],"tryItOutEnabled":false}');
            var oauthConfigObject = JSON.parse('{"scopeSeparator":" ","scopes":[],"useBasicAuthenticationWithAccessCodeGrant":false,"usePkceWithAuthorizationCodeGrant":false}');

            // Workaround for https://github.com/swagger-api/swagger-ui/issues/5945
            configObject.urls.forEach(function (item) {
                if (item.url.startsWith("http") || item.url.startsWith("/")) return;
                item.url = window.location.href.replace("index.html", item.url).split('#')[0];
            });

            // If validatorUrl is not explicitly provided, disable the feature by setting to null
            if (!configObject.hasOwnProperty("validatorUrl"))
                configObject.validatorUrl = null

            // If oauth2RedirectUrl isn't specified, use the built-in default
            if (!configObject.hasOwnProperty("oauth2RedirectUrl"))
                configObject.oauth2RedirectUrl = (new URL("oauth2-redirect.html", window.location.href)).href;

            // Apply mandatory parameters
            configObject.dom_id = "#swagger-ui";
            configObject.presets = [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset];
            configObject.layout = "StandaloneLayout";

            // Parse and add interceptor functions
            var interceptors = JSON.parse('{"RequestInterceptorFunction":null,"ResponseInterceptorFunction":null}');
            if (interceptors.RequestInterceptorFunction)
                configObject.requestInterceptor = parseFunction(interceptors.RequestInterceptorFunction);
            if (interceptors.ResponseInterceptorFunction)
                configObject.responseInterceptor = parseFunction(interceptors.ResponseInterceptorFunction);

            // Begin Swagger UI call region

            const ui = SwaggerUIBundle(configObject);

            ui.initOAuth(oauthConfigObject);

            // End Swagger UI call region

            window.ui = ui
        }
    </script>
</body>
</html>
.StatusCode -eq 200) {
             = True
            Write-Host " Swagger 端点正常" -ForegroundColor Green
        }
    } catch {
        Start-Sleep -Seconds 1
        ++
        Write-Host "." -NoNewline -ForegroundColor Gray
    }
}

# 打开浏览器
Write-Host ""
Write-Host "正在打开浏览器..." -ForegroundColor Cyan

# 尝试多种方式打开浏览器
 = @(
    "https://localhost:5001/swagger",
    "http://localhost:5000/swagger"
)

foreach ( in ) {
    try {
        Start-Process 
        Write-Host " 已打开: " -ForegroundColor Green
        Start-Sleep -Seconds 1
    } catch {
        Write-Host " 无法打开: " -ForegroundColor Red
    }
}

# 显示完成信息
Write-Host ""
Write-Host "========================================" -ForegroundColor Green
Write-Host "    启动完成！" -ForegroundColor Green
Write-Host "========================================" -ForegroundColor Green
Write-Host ""
Write-Host " Swagger API 文档地址:" -ForegroundColor White
Write-Host "   HTTPS: https://localhost:5001/swagger" -ForegroundColor Cyan
Write-Host "   HTTP:  http://localhost:5000/swagger" -ForegroundColor Cyan
Write-Host ""
Write-Host " 应用信息:" -ForegroundColor White
Write-Host "   进程ID: " -ForegroundColor Gray
Write-Host "   状态: 运行中" -ForegroundColor Green
Write-Host ""
Write-Host " 提示: 按 Ctrl+C 停止应用" -ForegroundColor Yellow
Write-Host ""

# 保持脚本运行，显示实时状态
Write-Host "按任意键退出此窗口（应用将继续运行）..." -ForegroundColor Yellow
 = System.Management.Automation.Internal.Host.InternalHost.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
